package rpcserver

type Engine struct {
	RouterGroup
	funcMap *RpcHandler
}

func New() *Engine {
	engine := &Engine{
		RouterGroup: RouterGroup{
			basePath: "",
			root:     true,
		},
		funcMap: NewRpcHandler(),
	}

	engine.RouterGroup.engine = engine
	return engine
}

func Default() *Engine {
	return New()
}

func (e *Engine) Handlers() *RpcHandler {
	return e.funcMap
}

type IRoutes interface {
	Func(string, RpcFunc) IRoutes
	Group(string) *RouterGroup
}

type RouterGroup struct {
	basePath string
	engine   *Engine
	root     bool
}

func (g *RouterGroup) Group(relativePath string) *RouterGroup {
	return &RouterGroup{
		basePath: g.calculateAbsolutePath(relativePath),
		engine:   g.engine,
	}
}

func (g *RouterGroup) handle(relativePath string, handler RpcFunc) IRoutes {
	absolutePath := g.calculateAbsolutePath(relativePath)
	g.engine.funcMap.HandleFunc(absolutePath, handler)
	return g
}

func (g *RouterGroup) calculateAbsolutePath(relativePath string) string {
	return joinPaths(g.basePath, relativePath)
}

func (g *RouterGroup) Func(relativePath string, handler RpcFunc) IRoutes {
	return g.handle(relativePath, handler)
}
